﻿/*
 * LegendNode
 * 
 * initial implementation : 20.11.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
//using System.Collections.Generic;
//using System.Text;
//using Petra.Gis.Geometry;
//using Petra.Gis.DataServices;
//using Petra.Gis.DataServices.Metadata;
//using Petra.Gis.ReferenceSystemServices;
using Petra.Gis.RenderingServices.PlanarBase.Support;


namespace Petra.Gis.RenderingServices.PlanarBase 
{


  

  /// <summary>
  /// Base class for all legend nodes. 
  /// Represents single map legend item organized as tree structure
  /// </summary>
  public abstract class LegendNodeBase : KeepRelationWith<LegendNodeBase>
  {

    //protected List<LegendNodeBase> childNodesData;
    
    //protected string _title;
    //protected LegendNodeType _nodeType;
    
    //protected List<LegendNode> _childNodes;
    //protected object _data; //todo: change to Linq.IEnumerable or DataReader or DataTable
    //protected PlanarMap _map;

    


    #region ctor


    /// <summary>
    /// xaml constr.
    /// </summary>
    protected LegendNodeBase() { }



    protected LegendNodeBase(LeafLegendNode parent, string title)
    //  :this()
    {
      ParentNode = parent;
      Title = title;
      //_childNodes = new Dictionary<string, LegendNode>();
    }



    //protected internal LegendNodeBase(LegendNode parent, object data)
    //{
    //  _parent = parent;
    //  _data = data;
    //}


    #endregion ctor


    #region members



    /// <summary>
    /// get/set legend node name
    /// </summary>
    public string Name { get; set; }



    
    /// <summary>
    /// set/set description for legend node
    /// </summary>
    public string Description { get; set; }





    /// <summary>
    /// get/set <c>LegendNodeBase</c> Title
    /// </summary>
    public virtual string Title
    { get; set; }




    /// <summary>
    /// determines whether this node is visible in legend
    /// </summary>
    public bool LegendVisible { get; set; }





    /// <summary>
    /// gets intendation level of this node in legend hierarchy
    /// </summary>
    public int TreeLevel
    {
      get 
      {
        if (ParentNode == null)
          return 0;
        else
          return ParentNode.TreeLevel + 1;
      }
    }





    ///// <summary>
    ///// temporary variable that holds reference to legend who created this node
    ///// after node is placed in legend into some node, this property gets null.
    ///// </summary>
    //private MapLegend _tmpLegend;

    /// <summary>
    /// gets MapLegend that this node belongs to.
    /// </summary>
    public MapLegend Legend
    {
      get
      {
        if (this is MapLegend)
          return (MapLegend)this;

        else
          return ParentNode.Legend;

      }
    }





    public LeafLegendNode ParentNode
    {
      get { return (LeafLegendNode)__parent; }
      protected set
      {

        //if (_nodeType != LegendNodeType.GroupNode)
        //  throw new InvalidOperationException("cant append into non grou type node");

        //null is disabled for LegendNodeBase
        if (value == null)
          throw new InvalidOperationException(@"error unsupported null as parent
                                                use RemoveNode() instead");

        //if parent changed....
        if (__parent != null && !__parent.Equals(value))
          throw new NotImplementedException("sorry not avail yet");

        __parent = value;
      }
    }





    /// <summary>
    /// gets current node type
    /// </summary>
    public LegendNodeTypeEnum NodeType
    { get; protected set; }





    ///// <summary>
    ///// this is for LegendChildNodes
    ///// </summary>
    ///// <param name="newParent"></param>
    //internal void SetParentNode(LegendNodeBase newParent)
    //{
    //  this.ParentNode = newParent;
    //}




//    private LeafLegendNode _parent;

//    /// <summary>
//    /// sets parent node for current node
//    /// </summary>
//    public virtual LeafLegendNode ParentNode
//    {
//      get { return _parent; }
//      protected set
//      {

//        //if (_nodeType != LegendNodeType.GroupNode)
//        //  throw new InvalidOperationException("cant append into non grou type node");

//        //null is disabled
//        if (value == null)
//          throw new InvalidOperationException(@"error unsupported null as parent
//                                                use RemoveNode() instead");

//        //if parent changed....
//        if (_parent != null && !_parent.Equals(value))
//          throw new NotImplementedException("sorry not avail yet");

//        _parent = value;
//      }
//    }





    ///// <summary>
    ///// inherited class might use this.
    ///// Usually reserved only for LeafNode...
    ///// </summary>
    //protected LegendChildNodes childNodes = null;


    ///// <summary>
    ///// List of child nodes for current node.
    ///// </summary>
    //public LegendChildNodes ChildNodes
    //{
    //  get { return childNodes; }
    //}




    ///// <summary>
    ///// appends new child node into ChildNodes collection of current instance of LeafLegendNode.
    ///// for other node types, throws error
    ///// </summary>
    ///// <param name="newChild">child node to append</param>
    ///// <returns></returns>
    //public virtual LegendNodeBase AppendChild(LegendNodeBase newChild)
    //{

    //  if (!(this is LeafLegendNode))
    //    throw new InvalidOperationException("cant append into non group node");

    //  childNodesData.Add(newChild);
    //  newChild.ParentNode = (LeafLegendNode)this;

    //  return newChild;
        

    //  ////if (_nodeType != LegendNodeType.GroupNode)
    //  ////  throw new InvalidOperationException("invalid command");

    //  //// if parent of newChild is not null then remove it from prev
    //  //if (newChild.ParentNode() != null)
    //  //  // reinsert existing node into another place
    //  //  // display order remains same
    //  //  // so must use removeNode instead of RemoveNode
    //  //  ((LeafLegendNode)newChild.ParentNode()).RemoveNode(newChild, false);
    //  //else
    //  //  // new node insert, put into displayOrder collection
    //  //  _legendDisplayOrder.Insert(0, newChild);

    //  //add to current collection
    //}


    #endregion members



  }
  
}
